<!-- 右侧属性表单 -->
<template>
  <div class="props-table">
    <div
      v-for="(item, prop) in finalProps"
      :key="prop" class="prop-item"
    >
      <span class="label" v-if="item">{{ item.title }}</span>
      <component
        v-if="item" :is="item.component" :[item.valueProp]="item.value"
        v-bind="item.formProps" class="prop-component"
        v-on="item.events"
      >
        <template v-if="item.options">
          <component
            :is="item.subComponent" v-for="opt in item.options"
            :key="opt.value" :value="opt.value"
          >
            <render-vnode :vNode="opt.label"></render-vnode>
          </component>
        </template>
      </component>
    </div>
  </div>
</template>

<script lang="ts">
import { type PropType } from 'vue'
import { type ITextDefaultProps } from '../defaultProps'
</script>
<script setup lang="ts">
import { computed, type VNode } from 'vue'
import { mapPropsToForms } from '@/propsMap'
import RenderVnode from './RenderVNode';

export interface IFormProps {
  component: string;
  subComponent?: string;
  value: string;
  formProps?: {[key:string]: any};
  title?: string;
  options?: { label:string | VNode, value:any }[];
  initialTransform?: (v:any) => any;
  // 绑定表单组件的value的 attribute key
  valueProp: string;
  eventName: string;
  events: { [key:string]: (e:any) => void };
}

const emits = defineEmits(['change']);

// 当前组件的属性以及属性值
const props = defineProps({
  props: {
    type: Object as PropType<any>,
    required: true
  }
})

// 当前组件的所有可改属性，对应的 最终的表单配置数据
const finalProps = computed(() => {
  const res = {} as { [key:string]: IFormProps }
  // 当前组件的所有可修改的属性
  const allProps = props.props
  Object.entries(allProps).forEach(([k, val]) => {
    const newK = k as keyof ITextDefaultProps
    // 组件的当前属性对应的表单配置
    const formCompConfig = mapPropsToForms[newK]
    if (formCompConfig) {
      const { valueProp = 'value', eventName = 'change', initialTransform, afterTransform } = formCompConfig;
      const newFormCompConfig: IFormProps = {
        ...formCompConfig,
        value: initialTransform ? initialTransform(val) : val,
        valueProp,
        eventName,
        events: {
          [eventName]: (e: any) => { emits('change', { k, val: afterTransform ? afterTransform(e) : e }) }
        }
      }
      res[newK] = newFormCompConfig;
    }
  })
  return res
})
</script>

<style scoped lang="less">
.prop-item {
  display: flex;
  margin-bottom: 10px;
  align-items: center;
}
.label {
  width: 28%;
}
.prop-component {
  width: 70%;
}
</style>